<template>
  <div class="Index">
    <div :class="['left', !unfold && 'leftShrink']">
      <div class="left-logo">
        <img :src="setting.logo" alt="" />
        <span :class="['setting-title', !unfold && 'setting-titleShrink']">
          {{ setting.title }}
        </span>
      </div>
      <el-menu
        background-color="#393e46"
        text-color="#fff"
        active-text-color="#ffd04b"
        style="border-right: none"
        :default-active="route.path"
        class="left-menu"
      >
        <template v-for="item in menuList" :key="item.path">
          <el-tooltip
            :visible="!unfold && item.meta.hover"
            effect="dark"
            placement="right"
          >
            <template #content>
              <strong style="font-size: 14px; padding: 2px">
                {{ item.meta.title }}
              </strong>
            </template>
            <el-menu-item
              v-if="!item.meta.hidden"
              :index="item.path"
              @click="goRoute"
              @mouseenter="
                () => {
                  item.meta.hover = true
                }
              "
              @mouseleave="
                () => {
                  item.meta.hover = false
                }
              "
            >
              <el-icon>
                <component :is="item.meta.icon"></component>
              </el-icon>

              <span :class="['meta-title', !unfold && 'meta-titleShrink']">
                {{ item.meta.title }}
              </span>
            </el-menu-item>
          </el-tooltip>
        </template>
      </el-menu>
    </div>
    <div :class="['right', !unfold && 'rightShrink']">
      <div class="right-top">
        <div
          :class="['rt-left', !unfold && 'rotate']"
          @click="handleClickUnfold"
        >
          <svgIcon name="unfoldRight" size="20"></svgIcon>
        </div>
        <div
          @click="
            () => {
              logout = true
            }
          "
          class="rt-right"
        >
          <img src="@/assets/images/avatar.jpg" alt="" />
        </div>
        <div v-show="logout" class="rtt-logout" @click="handleLogout">
          退出登录
        </div>
      </div>
      <div class="right-content">
        <router-view @SignIn="handleSignIn"></router-view>
      </div>
    </div>
    <el-dialog
      :show-close="false"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      v-model="dialogVisible"
    >
      <div class="animation">
        <div class="dot dot-1"></div>
        <div class="dot dot-2"></div>
        <div class="dot dot-3"></div>
      </div>
      <h2 class="dialog-title">签到中...</h2>
      <div class="dialog-content">
        <div
          v-for="(item, index) in showStudent"
          :key="index"
          class="studentInfo"
        >
          <img :src="`${setting.baseURL}/img/${item.image}`" alt="" />
          <p>{{ item.username }}</p>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <span style="margin-right: 20px">
            {{ showStudent.length }}/{{ studentInfo.length }}
          </span>
          <el-button type="primary" @click="endToSignIn">结束</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue'
// 引入用户相关的小仓库
import useTeacherStore from '@/store/modules/teacher'
const teacherStore: any = useTeacherStore()
// 引入设置标题与logo配置文件
import setting from '@/setting'
// 引入路由对象
import { useRouter, useRoute } from 'vue-router'
// 导入路由
import { constantRouter } from '@/router/routes'
// 教师签到相关接口
import {
  createWebSocket,
  reqTeacherStartSign,
  reqTeacherGetAllSign,
  reqTeacherCloseSign,
} from '@/api/signIn'
import { reqTeacherGetStudent } from '@/api/teacher'

// 使用 router 对象获取当前路由信息
const router = useRouter()
const route = useRoute()
// 定时器
let timer: any = null

// 创建WebSocket连接
const ws = createWebSocket(teacherStore.token)

// 导航栏数据
const menuList = ref<any>(constantRouter[0].children)
// 菜单栏是否展开
const unfold = ref(true)
// 退出界面是否展示
const logout = ref(false)
// 签到对话框的显示与隐藏
const dialogVisible = ref(false)
// 学生数据
const studentInfo = ref<any>([])
// 展示的学生数据
const showStudent = ref<any>([])
// 发起签到的数据
const signInData = ref<any>({})
// 签到数据
const signInInfo = ref<any>({})

// 点击菜单项的路由跳转
const goRoute = (vc: any) => {
  router.push(vc.index)
}

// 点击收缩菜单栏的回调
const handleClickUnfold = () => {
  unfold.value = !unfold.value
}

// 点击退出登录的按钮
const handleLogout = () => {
  // 数据清除
  localStorage.removeItem('User')
  router.push('login')
  ElMessage.success('退出成功')
}

// 子传父的签到信息
const handleSignIn = async (data: any) => {
  signInData.value = data
  timer = setTimeout(
    () => {
      endToSignIn()
    },
    Number(data.time) * 60000,
  )
  await teacherStartSign()
  await Promise.all([teacherGetAllSign(), teacherGetStudent()])

  dialogVisible.value = true
}

// 签到结束
const endToSignIn = async () => {
  clearTimeout(timer)
  await teacherCloseSign()
  signInData.value = {}
  signInInfo.value = {}
  dialogVisible.value = false
}

// 获取学生数据
const teacherGetStudent = async () => {
  const res = await reqTeacherGetStudent()
  if (res.code === 200) {
    studentInfo.value = res.data
  }
}

// 点击任意地方关闭设置
window.addEventListener('click', (e: any) => {
  if (logout.value && !e.target.closest('.rt-right')) {
    logout.value = false
  }
})

// 教师发起签到
const teacherStartSign = async () => {
  const res = await reqTeacherStartSign({
    context: signInData.value.title,
    endTime: getCurrentTimePlusNumSeconds(signInData.value.time),
  })
  if (res.code === 200) {
    ElMessage.success('签到已发起！')
  }
}

// 教师获取所有签到的信息
const teacherGetAllSign = async () => {
  const res = await reqTeacherGetAllSign()
  if (res.code === 200) {
    signInInfo.value = res.data[res.data.length - 1]
  }
  console.log(res.data)
}

// 教师关闭签到
const teacherCloseSign = async () => {
  const res = await reqTeacherCloseSign({ id: signInInfo.value.id })
  if (res.code === 200) {
    ElMessage.success('签到已关闭！')
  }
}

function getCurrentTimePlusNumSeconds(time: string) {
  // 获取当前时间
  const now = new Date()

  // 加上num秒
  now.setSeconds(now.getSeconds() + Number(time) * 60)

  // 格式化为"YYYY-MM-DD HH:MM:SS"的字符串
  const year = now.getFullYear()
  const month = (now.getMonth() + 1).toString().padStart(2, '0') // 月份是从0开始的，所以加1
  const day = now.getDate().toString().padStart(2, '0')
  const hours = now.getHours().toString().padStart(2, '0')
  const minutes = now.getMinutes().toString().padStart(2, '0')
  const seconds = now.getSeconds().toString().padStart(2, '0')

  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}

onMounted(() => {
  teacherStore.teacherGetInfo().then(() => {
    if (teacherStore.teacherInfo.modullimits !== 1) {
      menuList.value = menuList.value.filter((item: any) => {
        return item.name !== 'limits'
      })
    }
    if (teacherStore.teacherInfo.classlimits !== 1) {
      menuList.value = menuList.value.filter((item: any) => {
        return item.name !== 'class'
      })
    }
  })

  // 打开WebSocket连接
  ws.onopen = () => {
    console.log('WebSocket连接已打开')
  }
  // 监听WebSocket消息
  ws.onmessage = (event) => {
    const jsonMatch = event.data.match(/({.*})/s)

    if (jsonMatch && jsonMatch[1]) {
      const jsonString = jsonMatch[1]
      try {
        const data = JSON.parse(jsonString)
        // 根据解析后的数据执行业务逻辑
        if (data.type) {
          // 在这里添加处理业务逻辑的代码
          const studentId = data.user.id
          studentInfo.value.forEach((item: any) => {
            if (item.id === studentId) {
              showStudent.value.push(item)
            }
          })
        }
      } catch (error) {
        // 如果解析出错，输出错误信息
        console.error('数据解析错误:', error)
      }
    }
  }
  // 监听WebSocket错误
  ws.onerror = (error) => {
    console.error('WebSocket发生错误:', error)
  }
  // 监听WebSocket关闭
  ws.onclose = () => {
    console.log('WebSocket连接已关闭')
  }
})

window.onbeforeunload = async (e) => {
  e.stopImmediatePropagation()
  ws.close()
  if (Object.keys(signInInfo.value).length > 0) {
    clearTimeout(timer)
    await teacherCloseSign()
  }
  // 取消弹出窗口
  e.preventDefault()
  return null
}
onBeforeUnmount(async () => {
  ws.close()
  if (Object.keys(signInInfo.value).length > 0) {
    clearTimeout(timer)
    await teacherCloseSign()
  }
})
</script>

<style lang="scss" scoped>
.Index {
  height: 100vh;
  display: flex;
  overflow-x: hidden;

  & > .left {
    width: $leftWidth;
    height: 100%;
    color: #fff;
    transition: width 0.5s;
    background-color: #393e46;
    overflow-y: hidden;

    & > .left-logo {
      margin: 20px 10px;
      height: 40px;
      display: flex;
      align-items: center;

      & > img {
        height: 40px;
        width: 40px;
        margin: 0 10px 0 2px;
      }

      & > .setting-title {
        font-family: STXingkai;
        font-size: 20px;
        width: 80px;
        white-space: nowrap;
        transition: all 0.5s;
      }

      & > .setting-titleShrink {
        width: 0;
      }
    }

    & > .left-menu {
      .meta-title {
        width: 120px;
        white-space: nowrap;
        transition: width 0.5s;
        overflow: hidden;
      }

      .meta-titleShrink {
        width: 0;
      }
    }
  }

  & > .leftShrink {
    width: $leftWidth2;
  }

  & > .right {
    width: calc(100% - $leftWidth);
    height: 100%;
    transition: width 0.5s;

    & > .right-top {
      position: relative;
      height: $rightTopHeight;
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 0 20px;
      background-image: linear-gradient(to right, #eae9e6, #e3e1dd);

      & > .rt-left {
        transition: all 0.5s;
      }
      .rotate {
        transform: rotateY(180deg);
      }

      & > .rt-right {
        & > img {
          width: 40px;
          height: 40px;
          border-radius: 50%;
        }
      }

      & > .rtt-logout {
        z-index: 10;
        cursor: pointer;
        position: absolute;
        top: 58px;
        right: 15px;
        width: 100px;
        height: 50px;
        display: flex;
        color: #fff;
        font-weight: 600;
        justify-content: center;
        align-items: center;
        background-color: #393e46;
        border-radius: 10px;
      }
      .rtt-logout::after {
        content: '';
        width: 20px;
        height: 10px;
        position: absolute;
        top: -8px;
        right: 15px;
        background-color: #393e46;
        clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
      }

      & > .rtt-logout:hover {
        color: #409eff;
        background-color: lighten(#393e46, 20%);
      }

      .rtt-logout:hover::after {
        background-color: lighten(#393e46, 20%);
      }
    }

    & > .right-content {
      overflow-y: scroll;
      overflow-x: hidden;
      width: 100%;
      height: calc(100% - $rightTopHeight);
    }
  }

  & > .rightShrink {
    width: calc(100% - $leftWidth2);
  }
}
.animation {
  width: 60px;
  height: 60px;
  position: relative;
  top: 20px;
  left: 40px;
  transform: translate(-50%, -50%);
  animation: rotate-move 2s ease-in-out infinite;

  .dot {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
  }

  .dot-3 {
    background-color: #f74d75;
    animation:
      dot-3-move 2s ease infinite,
      index 6s ease infinite;
  }

  .dot-2 {
    background-color: #10beae;
    animation:
      dot-2-move 2s ease infinite,
      index 6s -4s ease infinite;
  }

  .dot-1 {
    background-color: #ffe386;
    animation:
      dot-1-move 2s ease infinite,
      index 6s -2s ease infinite;
  }

  @keyframes dot-3-move {
    20% {
      transform: scale(1);
    }
    45% {
      transform: translateY(-5px) scale(0.6);
    }
    60% {
      transform: translateY(-23px) scale(0.6);
    }
    80% {
      transform: translateY(-23px) scale(0.6);
    }
    100% {
      transform: translateY(0px) scale(1);
    }
  }

  @keyframes dot-2-move {
    20% {
      transform: scale(1);
    }
    45% {
      transform: translate(-4px, 3px) scale(0.6);
    }
    60% {
      transform: translate(-20px, 15px) scale(0.6);
    }
    80% {
      transform: translate(-20px, 15px) scale(0.6);
    }
    100% {
      transform: translateY(0px) scale(1);
    }
  }

  @keyframes dot-1-move {
    20% {
      transform: scale(1);
    }
    45% {
      transform: translate(4px, 3px) scale(0.6);
    }
    60% {
      transform: translate(20px, 15px) scale(0.6);
    }
    80% {
      transform: translate(20px, 15px) scale(0.6);
    }
    100% {
      transform: translateY(0px) scale(1);
    }
  }

  @keyframes rotate-move {
    55% {
      transform: translate(-50%, -50%) rotate(0deg);
    }
    80% {
      transform: translate(-50%, -50%) rotate(360deg);
    }
    100% {
      transform: translate(-50%, -50%) rotate(360deg);
    }
  }

  @keyframes index {
    0%,
    100% {
      z-index: 3;
    }
    33.3% {
      z-index: 2;
    }
    66.6% {
      z-index: 1;
    }
  }
}

.dialog-title {
  position: absolute;
  top: 40px;
  left: 100px;
}

.dialog-content {
  margin-top: 20px;
  display: flex;
  flex-wrap: wrap;

  & > .studentInfo {
    width: 60px;
    display: flex;
    flex-wrap: wrap;
    font-size: 16px;
    margin: 0 20px 30px 20px;
    justify-content: center;

    & > img {
      width: 60px;
      height: 60px;
      border-radius: 50%;
      margin-bottom: 10px;
    }
  }
}
</style>
